#include "ExportParameterVisitorUtils.h"
#include "../../utils/instanceof.h"

// here, the list std::list<Object_ptr >, it's original java version will put String, int, double, etc... in this list. However only the size of the list is used, the elements in the list is not used at all. so,
// one way is to find a generic list in c++;
// the other way in create a base class, and some wrapper class entends base for string_ptr , int, double ...
// or, just keep the number of the parameters, not using the list at all.

BOOL_ptr ExportParameterVisitorUtils::exportParamterAndAccept(
    Object_list_ptr parameters,
    SQLExpr_list_ptr  list)
{

  for (std::list<SQLExpr_ptr>::iterator it = list->begin(); it != list->end(); it++)
  {
    SQLExpr_ptr param = *it;

    SQLExpr_ptr result = exportParameter(parameters, param);
    if (result != param)
    {

      // delete (*it);

      (*it) = result;
    }
  }

  return BOOL::FALSE;
}

SQLExpr_ptr ExportParameterVisitorUtils::exportParameter(
    Object_list_ptr parameters,
    SQLExpr_ptr param)
{
  // Object_ptr value = nullptr;
  // BOOL_ptr replace = BOOL::FALSE;

  // if (instanceof <SQLExpr, SQLCharExpr>(param))
  // {
  //   value = (dynamic_cast<SQLCharExpr *>(param))->getText();
  //   // String vStr = (String) value;
  //   //            if (vStr.length() > 1) {
  //   //                value = StringUtils.removeNameQuotes(vStr);
  //   //            }
  //   replace = BOOL::TRUE;
  // }
  // else if (instanceof <SQLExpr, SQLNCharExpr>(param))
  // {
  //   value = dynamic_cast<SQLNCharExpr *>(param)->getText();
  //   replace = BOOL::TRUE;
  // }
  // else if (param instanceof SQLBooleanExpr)
  // {
  //   value = ((SQLBooleanExpr)param).getBooleanValue();
  //   replace = BOOL::TRUE;
  // }
  // else if (param instanceof SQLNumericLiteralExpr)
  // {
  //   value = ((SQLNumericLiteralExpr)param).getNumber();
  //   replace = BOOL::TRUE;
  // }
  // else if (param instanceof SQLHexExpr)
  // {
  //   value = ((SQLHexExpr)param).toBytes();
  //   replace = BOOL::TRUE;
  // }
  // else if (param instanceof SQLTimestampExpr)
  // {
  //   value = ((SQLTimestampExpr)param).getValue();
  //   replace = BOOL::TRUE;
  // }
  // else if (param instanceof SQLDateExpr)
  // {
  //   value = ((SQLDateExpr)param).getValue();
  //   replace = BOOL::TRUE;
  // }
  // else if (param instanceof SQLTimeExpr)
  // {
  //   value = ((SQLTimeExpr)param).getValue();
  //   replace = BOOL::TRUE;
  // }
  // else if (param instanceof SQLListExpr)
  // {
  //   SQLListExpr list = ((SQLListExpr)param);

  //   List<Object> listValues = new ArrayList<Object>();
  //   for (int i = 0; i < list.getItems().size(); i++)
  //   {
  //     SQLExpr listItem = list.getItems().get(i);

  //     if (listItem instanceof SQLCharExpr)
  //     {
  //       Object listValue = ((SQLCharExpr)listItem).getText();
  //       listValues.add(listValue);
  //     }
  //     else if (listItem instanceof SQLBooleanExpr)
  //     {
  //       Object listValue = ((SQLBooleanExpr)listItem).getBooleanValue();
  //       listValues.add(listValue);
  //     }
  //     else if (listItem instanceof SQLNumericLiteralExpr)
  //     {
  //       Object listValue = ((SQLNumericLiteralExpr)listItem).getNumber();
  //       listValues.add(listValue);
  //     }
  //     else if (listItem instanceof SQLHexExpr)
  //     {
  //       Object listValue = ((SQLHexExpr)listItem).toBytes();
  //       listValues.add(listValue);
  //     }
  //   }

  //   if (listValues.size() == list.getItems().size())
  //   {
  //     value = listValues;
  //     replace = BOOL::TRUE;
  //   }
  // }
  // else if (param instanceof SQLNullExpr)
  // {
  //   value = null;
  //   replace = BOOL::TRUE;
  // }

  // if (replace)
  // {
  //   SQLObject parent = param.getParent();
  //   if (parent != null)
  //   {
  //     List<SQLObject> mergedList = null;
  //     if (parent instanceof SQLBinaryOpExpr)
  //     {
  //       mergedList = ((SQLBinaryOpExpr)parent).getMergedList();
  //     }
  //     if (mergedList != null)
  //     {
  //       List<Object> mergedListParams = new ArrayList<Object>(mergedList.size() + 1);
  //       for (int i = 0; i < mergedList.size(); ++i)
  //       {
  //         SQLObject item = mergedList.get(i);
  //         if (item instanceof SQLBinaryOpExpr)
  //         {
  //           SQLBinaryOpExpr binaryOpItem = (SQLBinaryOpExpr)item;
  //           exportParameter(mergedListParams, binaryOpItem.getRight());
  //         }
  //       }
  //       if (mergedListParams.size() > 0)
  //       {
  //         mergedListParams.add(0, value);
  //         value = mergedListParams;
  //       }
  //     }
  //   }

  //   if (parameters != null)
  //   {
  //     parameters.add(value);
  //   }

  //   return new SQLVariantRefExpr("?");
  // }

  return param;
}

void ExportParameterVisitorUtils::exportParameter(
    Object_list_ptr parameters,
    SQLBinaryOpExpr *x)
{
  if (instanceof <SQLExpr, SQLLiteralExpr>(x->getLeft()) &&
      instanceof <SQLExpr, SQLLiteralExpr>(x->getRight()) && x->getOperator()->isRelational())
  {
    return;
  }

  {
    SQLExpr_ptr leftResult = ExportParameterVisitorUtils::exportParameter(parameters, x->getLeft());
    if (leftResult != x->getLeft())
    {
      x->setLeft(leftResult);
    }
  }

  {
    SQLExpr_ptr rightResult = exportParameter(parameters, x->getRight());
    if (rightResult != x->getRight())
    {
      x->setRight(rightResult);
    }
  }
}

void ExportParameterVisitorUtils::exportParameter(
    Object_list_ptr parameters,
    SQLBetweenExpr *x)
{
  {
    SQLExpr_ptr result = exportParameter(parameters, x->getBeginExpr());
    if (result != x->getBeginExpr())
    {
      x->setBeginExpr(result);
    }
  }

  {
    SQLExpr_ptr result = exportParameter(parameters, x->getEndExpr());
    if (result != x->getBeginExpr())
    {
      x->setEndExpr(result);
    }
  }
}
